package org.openkanban.client.login;

import org.openkanban.client.Main;
import org.openkanban.client.ui.board.BoardView;
import org.openkanban.client.ui.footer.Footer;
import org.openkanban.client.ui.presenter.PreparedRequest;
import org.openkanban.client.util.RootPanel;
import org.openkanban.client.util.StringUtils;
import org.openkanban.shared.dto.UserDto;

import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Cookies;
import com.smartgwt.client.types.AnimationEffect;
import com.smartgwt.client.widgets.AnimationCallback;

/**
 * Used to handle log-in functionality.
 * 
 */
public abstract class LogIn {

    private static UserDto userDto;

    public static void setLoggedInUser(UserDto userDto) {
	LogIn.userDto = userDto;
	Cookies.setCookie("userId", userDto.getUserId().toString());
    }

    /**
     * Checks if user is logged-in by reading cookie data. If needed log-in
     * requests will send to the server.
     */
    public static void initLogin() {
	loadCredentialsFromCookies();

	if (userDto.getUserId() != null) {
	    PreparedRequest prepReq = new PreparedRequest("user", "login");
	    prepReq.sendAsyncRequest(new RequestCallback() {
		@Override
		public void onResponseReceived(Request request, Response response) {
		    if (response.getStatusCode() == 200) {
			processLogIn();
		    }
		    if (response.getStatusCode() == 401) {
			userDto = null;
			RootPanel.main.getVlMain().animateShow(AnimationEffect.FADE, null, 1000);
		    }
		}

		@Override
		public void onError(Request request, Throwable exception) {
		}
	    });
	} else {
	    RootPanel.main.getVlMain().animateShow(AnimationEffect.FADE, null, 1000);
	}
    }

    private static void loadCredentialsFromCookies() {
	if (userDto == null) {
	    userDto = new UserDto();
	}
	if (StringUtils.isNumeric(Cookies.getCookie("userId"))) {
	    userDto.setUserId(Long.parseLong(Cookies.getCookie("userId")));
	}
    }

    /**
     * GUI block for log in
     */
    public static void processLogIn() {
	RootPanel.main.getCometClient().connect(userDto.getEmail(), userDto.getPassword());

	RootPanel.main.setBoard(new BoardView());
	RootPanel.main.setFooter(new Footer());

	RootPanel.main.getAdminPanel().getVsLoginVStack().hide();
	RootPanel.main.getAdminPanel().getLoginButton().hide();
	RootPanel.main.getAdminPanel().getSignUpButton().hide();

	RootPanel.main.getAdminPanel().getUserAccountButton().show();
	RootPanel.main.getAdminPanel().getLogoutButton().show();

	RootPanel.main.getLayout().removeMembers(RootPanel.main.getLayout().getMembers());
	RootPanel.main.getLayout().addMember(RootPanel.main.getBoard());
	RootPanel.main.getVlMain().addChild(RootPanel.main.getFooter());
	RootPanel.main.getFooter().moveAbove(RootPanel.main.getBoard());
	RootPanel.main.getFooter().show();
    }

    public static void setLogout() {
	Cookies.removeCookie("userId");
	Cookies.removeCookie("sessionId");
    }

    /**
     * GUI block for log out
     */
    public static void processLogOut() {
	userDto = null;

	RootPanel.main.getVlMain().animateHide(AnimationEffect.FADE, new AnimationCallback() {
	    @Override
	    public void execute(boolean earlyFinish) {
		RootPanel.main.getCometClient().disconnect();

		RootPanel.main.getAdminPanel().getUserAccountButton().hide();
		RootPanel.main.getAdminPanel().getNewBoardButton().hide();
		RootPanel.main.getAdminPanel().getLogoutButton().hide();
		RootPanel.main.getAdminPanel().getLoginButton().show();
		RootPanel.main.getAdminPanel().getSignUpButton().show();

		RootPanel.main.getLayout().removeMembers(RootPanel.main.getLayout().getMembers());

		RootPanel.main.getLayout().addMember(RootPanel.main.getWelcome());
		RootPanel.main.getVlMain().removeChild(RootPanel.main.getFooter());

		RootPanel.main.getVlMain().animateShow(AnimationEffect.FADE, null, Main.DEFAULT_FADE_DURATION);
	    }
	}, Main.DEFAULT_FADE_DURATION);
    }

    public static UserDto getUserDto() {
	return userDto;
    }

    public static void setUserDto(UserDto userDto) {
	LogIn.userDto = userDto;
    }

    public static boolean userDtoExists() {
	return userDto != null && userDto.getUserId() != null;
    }

}
